﻿// owner 蒋家伟

#include "SerialPortHardwareDevice.h"

#include "SerialPortHardwareCompoent.h"
#include "ISerialPortHardwareExternalData.h"
#include "Dbg_Warn_Define.h"

using namespace jsdk;

OwnerPtr<SerialPortHardwareDevice> jsdk::SerialPortHardwareDevice::create(OwnerPtr<ISerialPortHardwareExternalData> opSerialPortHardwareExternalData)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSerialPortHardwareExternalData, L"外部数据为空", L"蒋家伟", L"2023-08-03");
    OwnerPtr<SerialPortHardwareDevice> opSerialPortHardwareDevice = NEW_AS_OWNERPTR(SerialPortHardwareDevice);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSerialPortHardwareDevice, L"串口硬件设备创建失败", L"蒋家伟", L"2023-08-03");
    opSerialPortHardwareDevice->m_opSerialPortHardwareCompoent.swap(SerialPortHardwareCompoent::create(opSerialPortHardwareExternalData->getHardwareEventHandler(), opSerialPortHardwareExternalData->getSerialPortEventHandler()));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSerialPortHardwareDevice->m_opSerialPortHardwareCompoent, L"串口硬件组件创建失败", L"蒋家伟", L"2023-08-03");
    opSerialPortHardwareDevice->m_opExternalData.swap(opSerialPortHardwareExternalData);

    if (opSerialPortHardwareDevice->m_opExternalData)
    {
        opSerialPortHardwareDevice->m_opExternalData->setOwnerDevice(opSerialPortHardwareDevice.get());
    }

    return std::move(opSerialPortHardwareDevice);
}

bool jsdk::SerialPortHardwareDevice::start()
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(m_opSerialPortHardwareCompoent, L"串口硬件组件初始化失败", L"蒋家伟", L"2023-08-03");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(m_opExternalData, L"外部参数无效", L"蒋家伟", L"2023-08-03");

    std::string portName;
    int baudRate = 0;
    short dataBits = 8;
    short stopBits = 1;
    short parity = 0;
    short flowControl = 0;
    bool success = m_opExternalData->getSerialPortParameter(
        portName, 
        baudRate, 
        dataBits,
        stopBits,
        parity,
        flowControl
        );

    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"从外部数据中获取串口参数失败", L"蒋家伟", L"2023-08-03");
    return m_opSerialPortHardwareCompoent->start(portName, baudRate, dataBits, stopBits, parity, flowControl);
}

void jsdk::SerialPortHardwareDevice::stop()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opSerialPortHardwareCompoent, L"串口硬件组件初始化失败", L"蒋家伟", L"2023-08-03");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opExternalData, L"外部参数无效", L"蒋家伟", L"2023-08-03");
    m_opSerialPortHardwareCompoent->stop();
    m_opExternalData->stop();
}

void jsdk::SerialPortHardwareDevice::addTask(const TaskId & taskId) const
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opSerialPortHardwareCompoent, L"串口硬件组件初始化失败", L"蒋家伟", L"2023-08-03");
    m_opSerialPortHardwareCompoent->addTask(taskId);
}

const std::wstring jsdk::SerialPortHardwareDevice::getDeviceName() const
{
    DBG_WARN_AND_RETURN_UNLESS(m_opExternalData, L"",L"串口硬件组件初始化失败", L"蒋家伟", L"2023-08-03");
    return m_opExternalData->getHardwareName();
}

const IDeviceExternalData* jsdk::SerialPortHardwareDevice::getExternalData() const
{
    return m_opExternalData.get();
}

IDeviceExternalData* jsdk::SerialPortHardwareDevice::getExternalDataFW()
{
    return m_opExternalData.get();
}

void jsdk::SerialPortHardwareDevice::sendMessage(std::string && msg, int64_t length) const
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opSerialPortHardwareCompoent, L"串口硬件组件初始化失败", L"蒋家伟", L"2023-08-03");
    m_opSerialPortHardwareCompoent->sendMessage(std::move(msg), length);
}

void jsdk::SerialPortHardwareDevice::reConnect() const
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opSerialPortHardwareCompoent, L"串口硬件组件初始化失败", L"蒋家伟", L"2023-08-03");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opExternalData, L"外部参数无效", L"蒋家伟", L"2023-08-03");

    std::string portName;
    int baudRate = 0;
    short dataBits = 0;
    short stopBits = 0;
    short parity = 0;
    short flowControl = 0;
    bool success = m_opExternalData->getSerialPortParameter(
        portName,
        baudRate,
        dataBits,
        stopBits,
        parity,
        flowControl
        );

    DBG_WARN_AND_RETURN_VOID_UNLESS(success, L"从外部数据中获取ip地址与端口失败", L"蒋家伟", L"2023-08-03");
    m_opSerialPortHardwareCompoent->reConnect(portName, baudRate, dataBits, stopBits, parity, flowControl);
}

bool jsdk::SerialPortHardwareDevice::isOnline() const
{
    if (m_opSerialPortHardwareCompoent)
    {
        return m_opSerialPortHardwareCompoent->isOnline();
    }
    return false;
}

